package com.t2t.top.framework.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;

/**
 * 序列化工具类
 *
 * @author yangpengfei
 */
public class SerializeUtils {
    private static final Log logger = LogFactory.getLog(SerializeUtils.class);

    /**
     * 范型自动检查是否实现序列化
     */
    public static <E extends Serializable> byte[] serialize(E o) {
        if (o == null) {
            throw new NullPointerException("Can't serialize null");
        }

        byte[] rv = null;
        ByteArrayOutputStream bos = null;
        ObjectOutputStream os = null;
        try {
            bos = new ByteArrayOutputStream();
            os = new ObjectOutputStream(bos);
            os.writeObject(o);
            rv = bos.toByteArray();
        } catch (IOException e) {
            throw new IllegalArgumentException("Non-serializable object", e);
        } finally {
            closeIO(os);
            closeIO(bos);
        }
        return rv;
    }

    private static void closeIO(Closeable io) {
        try {
            io.close();
        } catch (IOException e) {
            logger.error("IO关闭失败! ", e);
        }
    }

    /**
     * 自动根据结果转换类型
     */
    @SuppressWarnings("unchecked")
    public static <T> T deserialize(byte[] in) {
        T rv = (T) deserializeObject(in);
        return rv;
    }

    /**
     * 自动根据结果转换类型
     */
    public static Object deserializeObject(byte[] in) {
        if (in == null || in.length == 0) {
            return null;
        }
        Object rv = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream is = null;
        try {
            bis = new ByteArrayInputStream(in);
            is = new ObjectInputStream(bis);
            rv = is.readObject();
        } catch (IOException e) {
            logger.warn("Caught IOException decoding " + (in == null ? 0 : in.length) + " bytes of data", e);
        } catch (ClassNotFoundException e) {
            logger.warn("Caught CNFE decoding " + (in == null ? 0 : in.length) + " bytes of data", e);
        } finally {
            closeIO(is);
            closeIO(bis);
        }
        return rv;
    }

}
